import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.event.ActionEvent;
import java.awt.event.MouseAdapter;
import java.awt.event.MouseEvent;
import javax.swing.AbstractAction;
import javax.swing.BorderFactory;
import javax.swing.JFrame;
import javax.swing.JMenu;
import javax.swing.JMenuBar;
import javax.swing.JMenuItem;
import javax.swing.JPanel;

public class main {

	public static void main(String[] args) {
		
		// Create Frame for GUI
		JFrame frame = new JFrame("CS Paint");
		frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
		frame.setResizable(false);
		frame.setSize(250, 250);
		frame.setVisible(true);
		
		// Create canvas on which to paint
		PaintCanvas canvas = new PaintCanvas();
		
		// Create Menus
		JMenuBar menuBar = new JMenuBar();
		JMenu options = new JMenu("Options");
		JMenu colorsSub = new JMenu("Set Color");
		
		// Menu items and actions
		JMenuItem black = new JMenuItem("Black");
		black.setAction(new ColorAction(canvas, Color.BLACK));
		black.setText("Black");
		JMenuItem red = new JMenuItem("Red");
		red.setAction(new ColorAction(canvas, Color.RED));
		red.setText("Red");
		JMenuItem blue = new JMenuItem("Blue");
		blue.setAction(new ColorAction(canvas, Color.BLUE));
		blue.setText("Blue");
		JMenuItem green = new JMenuItem("Green");
		green.setAction(new ColorAction(canvas, Color.GREEN));
		green.setText("Green");
		
		// Populate menus and submenus
		colorsSub.add(black);
		colorsSub.add(red);
		colorsSub.add(blue);
		colorsSub.add(green);
		
		options.add(colorsSub);
		menuBar.add(options);
		
		// Add menus to frame
		frame.setJMenuBar(menuBar);
		
		// Add canvas to frame
		frame.add(canvas);
		frame.pack();
	}
	

}

class PaintCanvas extends JPanel {
	
	// Pixel grid arrays hold information on corresponding pixel locations
	final int SIZE = 250;
	Color brushColor = Color.BLACK;
	boolean[][] pixels = new boolean[SIZE][SIZE];
	Color[][] colors = new Color[SIZE][SIZE];
	
	public PaintCanvas() {
		setBorder(BorderFactory.createRaisedBevelBorder());
		
		// Create listeners for mouse events
		addMouseListener(new MouseAdapter() {
            public void mousePressed(MouseEvent e) {
                addPixel(e.getX(),e.getY());
            }
        });

        addMouseMotionListener(new MouseAdapter() {
            public void mouseDragged(MouseEvent e) {
                addPixel(e.getX(),e.getY());
            }
        });

	}
	
	public Dimension getPreferredSize() {
		return new Dimension(SIZE, SIZE);
	}
	
	public void addPixel(int x, int y) {
		
		if(x < SIZE && y < SIZE) {
			pixels[x][y] = true;
			colors[x][y] = brushColor;
			
			// Repaint only surrounding area for efficiency
			repaint(x, y, 2, 2);
		}
	}
	
	public void paintComponent(Graphics g) {
		g.drawString("Paint Canvas", 10, 20);
		
		// Loop through each pixel in the grid
		for(int x = 0; x < SIZE; x ++) {
			for(int y = 0; y < SIZE; y ++) {
				
				// 
				if(pixels[x][y]) {
					g.setColor(colors[x][y]);
					g.drawRect(x, y, 1, 1);
				}
			}
		}
	}
}

class ColorAction extends AbstractAction {

	PaintCanvas canvas;
	Color color;
	
	public ColorAction(PaintCanvas canvas, Color color) {
		this.canvas = canvas;
		this.color = color;
	}
	@Override
	public void actionPerformed(ActionEvent arg0) {
		canvas.brushColor = color;
	}
}